﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace NRapid.Owin
{
    /// <summary>
    /// 输出Html类
    /// </summary>
    public class HtmlWriter : IDisposable
    {
        /// <summary>
        /// html内容输出类
        /// </summary>
        public TextWriter writer = null;
        /// <summary>
        /// html header头
        /// </summary>
        public IDictionary<string, string[]> headers = null;
        /// <summary>
        /// owin 参数
        /// </summary>
        public IDictionary<string, object> environment = null;
        Stream stream = null;
        /// <summary>
        /// Html类初始化
        /// </summary>
        /// <param name="environment">owin参数</param>
        /// <param name="headers">headers头</param>
        public HtmlWriter(IDictionary<string, object> environment,IDictionary<string,string[]> headers)
        {
            this.environment = environment;
            stream = (Stream)environment["owin.ResponseBody"];
            headers = (IDictionary<string, string[]>)environment["owin.ResponseHeaders"];
            writer = new StreamWriter(stream, Encoding.UTF8);
            this.headers = headers;
        }
        /// <summary>
        /// html静态文件输出
        /// </summary>
        /// <param name="fileName">文件名</param>
        public HtmlWriter(string fileName)
        {
            stream = new FileStream(fileName, FileMode.Create, FileAccess.Write);
            writer = new StreamWriter(stream);
        }
        /// <summary>
        /// 写入状态码
        /// </summary>
        /// <param name="statusCode"></param>
        public void WriteStatusCode(int statusCode)
        {
            environment["owin.ResponseStatusCode"] = statusCode;
        }
        /// <summary>
        /// 写入html头
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="value">value</param>
        public void WriteHeader(string key, string value)
        {
            if (this.headers.ContainsKey(key))
            {
                this.headers[key] = new string[] { value };
            }
            else
            {
                this.headers.Add(key, new string[] { value });
            }
        }
        /// <summary>
        /// Add a new cookie and value
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void SetCookie(string key, string value)
        {
            WriteHeader("Set-Cookie", Uri.EscapeDataString(key) + "=" + Uri.EscapeDataString(value) + "; path=/");
        }
        /// <summary>
        /// Sets an expired cookie
        /// </summary>
        /// <param name="key"></param>
        public void SetExpiredCookie(string key)
        {
            string deleteCookies =  Uri.EscapeDataString(key) + "=; expires=Thu, 01-Jan-1970 00:00:00 GMT" ;
            WriteHeader("Set-Cookie", deleteCookies);
        }
        /// <summary>
        /// 写入重定向头
        /// </summary>
        /// <param name="url"></param>
        public void WriteRedirectHeader(string url)
        {
            WriteHeader("Location", url);
        }
        /// <summary>
        /// 输出
        /// </summary>
        public void Flush()
        {
            this.stream.Flush();
            this.writer.Flush();
        }
        /// <summary>
        /// 关闭输出流并输出
        /// </summary>
        public void Close()
        {
            this.stream.Dispose();
            this.writer.Dispose();
        }
        /// <summary>
        /// 输出流
        /// </summary>
        /// <param name="buffer">字节数组</param>
        public void Write(byte[] buffer)
        {
            stream.Write(buffer, 0, buffer.Length);
        }
        /// <summary>
        /// 输出流
        /// </summary>
        /// <param name="buffer">字节数组</param>
        /// <param name="offset">起始位置</param>
        /// <param name="count">长度</param>
        public void Write(byte[] buffer,int offset,int count)
        {
            stream.Write(buffer, offset, count);
        }
        /// <summary>
        /// 输出字符串
        /// </summary>
        /// <param name="value"></param>
        public void Write(string value)
        {
            writer.Write(value);
        }
        /// <summary>
        /// 当未调用Close函数时，系统自动调用Dispose
        /// </summary>
        public void Dispose()
        {
            this.stream.Dispose();
            this.writer.Dispose();
        }
    }
}
